package com.mlnx.bptp.body;


import com.mlnx.bptp.Codec;
import com.mlnx.bptp.exception.InvalidPacketException;
import com.mlnx.bptp.util.DecodeCRC16;
import com.mlnx.bptp.util.ReadUtils;
import com.mlnx.common.utils.MyLog;

import java.nio.ByteBuffer;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


/**
 * @author zzb
 * @create 2019/3/25 13:30
 */
public class Body implements Codec {
    private MyLog log = MyLog.getLog(this.getClass());
    private static final ByteBuffer buffer = ByteBuffer.allocate(5000);

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm");

    private BpBody bpBody;
    private int patientId;
    private String deviceId;
    private String rectify;// 为矫正时间
    private DeviceState deviceState;
    private Command command;
    private PacketType packetType;
    private DetectTime detectTime;
    private IsBegin isBegin;
    private DetectState detectState;
    private Integer electric;//电量
    private String synData;// 同步时间


    public String getSynData() {
        return synData;
    }

    public void setSynData(String synData) {
        this.synData = synData;
    }

    public Integer getElectric() {
        return electric;
    }

    public void setElectric(Integer electric) {
        this.electric = electric;
    }

    public String getRectify() {
        return rectify;
    }

    public void setRectify(String rectify) {
        this.rectify = rectify;
    }

    public DetectState getDetectState() {
        return detectState;
    }

    public void setDetectState(DetectState detectState) {
        this.detectState = detectState;
    }

    public IsBegin getIsBegin() {
        return isBegin;
    }

    public void setIsBegin(IsBegin isBegin) {
        this.isBegin = isBegin;
    }

    public DetectTime getDetectTime() {
        return detectTime;
    }

    public void setDetectTime(DetectTime detectTime) {
        this.detectTime = detectTime;
    }

    public BpBody getBpBody() {
        return bpBody;
    }

    public void setBpBody(BpBody bpBody) {
        this.bpBody = bpBody;
    }


    public DeviceState getDeviceState() {
        return deviceState;
    }

    public void setDeviceState(DeviceState deviceState) {
        this.deviceState = deviceState;
    }

    public Command getCommand() {
        return command;
    }

    public void setCommand(Command command) {
        this.command = command;
    }

    public PacketType getPacketType() {
        return packetType;
    }

    public void setPacketType(PacketType packetType) {
        this.packetType = packetType;
    }



    public int getPatientId() {
        return patientId;
    }

    public void setPatientId(int patientId) {
        this.patientId = patientId;
    }

    public String getDeviceId() {
        return deviceId;
    }

    public void setDeviceId(String deviceId) {
        this.deviceId = deviceId;
    }

    @Override
    public void init() {
        bpBody = new BpBody();
        detectTime = new DetectTime();
        isBegin = new IsBegin();
        detectState = new DetectState();
    }

    @Override
    public void decode(ByteBuffer buf) throws InvalidPacketException, ParseException {
        command = Command.decode(ReadUtils.readData(buf));
        switch (command) {
            case LAST_BP_RESULT:
                break;
            case DEVICE_STATE://设备状态
                deviceState = DeviceState.decode(ReadUtils.readData(buf));
                if (deviceState == DeviceState.STOP_BP_DETECT) {
                    packetType = PacketType.ASK_DEVICE_PACKET;
                }
                log.debug("设备状态：" + deviceState.getDescription());

                break;
            case BEGIN://编程启动
                packetType = PacketType.PROGRAMMING;
                log.debug("回复服务器重新编程");
                break;
            case RECEIVE_DEVICE_ID://获取设备ID
                deviceId = ReadUtils.readString(buf);
                packetType = PacketType.REG_PACKET;
                log.debug("设备ID:" + deviceId);
                break;
            case RECEIVE_BP_RESULT://得到血压数据
                byte[] bs = new byte[15];
                buf.get(bs);
                Integer rec=(bs[0] & 0x000000ff);
                if (!rec.equals(1)) {
                    bpBody.setRecord(bs[0] & 0x000000ff);
                    bpBody.setSbp(bs[2] & 0x000000ff);
                    bpBody.setDbp(bs[4] & 0x000000ff);
                    bpBody.setHr(bs[6] & 0x000000ff);
                    int year = bs[7] & 0x000000ff;
                    int mouth = bs[8] & 0x000000ff;
                    int day = bs[9] & 0x000000ff;
                    int hour = bs[10] & 0x000000ff;
                    int min = bs[11] & 0x000000ff;
                    int position = bs[13] & 0x000000ff;
                    int method = bs[14] & 0x000000ff;
                    String time = "20" + year + "-" + mouth + "-" + day + " " + hour + "-" + min;
                    Date dt = sdf.parse(time);
                    bpBody.setReceiveTime(dt.getTime());
                    String pos = null;

                    if (position == 0) {
                        pos = "平躺";
                    } else if (position == 1) {
                        pos = "站立或静坐";
                    } else if (position == 2) {
                        pos = "轻微运动";
                    } else if (position == 3) {
                        pos = "剧烈运动";
                    }
                    bpBody.setPosition(pos);
                    bpBody.setMethod(method);
                    packetType = PacketType.ASK_RECROD;
                    log.debug("第: " + (bs[0] & 0x000000ff)+"条历史血压数据"+bpBody.toString());
                } else {
                    bpBody.setRecord(bs[0] & 0x000000ff);
                    bpBody.setSbp(bs[2] & 0x000000ff);
                    bpBody.setDbp(bs[4] & 0x000000ff);
                    bpBody.setHr(bs[6] & 0x000000ff);
                    int year = bs[7] & 0x000000ff;
                    int mouth = bs[8] & 0x000000ff;
                    int day = bs[9] & 0x000000ff;
                    int hour = bs[10] & 0x000000ff;
                    int min = bs[11] & 0x000000ff;
                    int position = bs[13] & 0x000000ff;
                    int method = bs[14] & 0x000000ff;
                    String time = "20" + year + "-" + mouth + "-" + day + " " + hour + "-" + min;
                    Date dt = sdf.parse(time);
                    bpBody.setReceiveTime(dt.getTime());
                    String pos = null;

                    if (position == 0) {
                        pos = "平躺";
                    } else if (position == 1) {
                        pos = "站立或静坐";
                    } else if (position == 2) {
                        pos = "轻微运动";
                    } else if (position == 3) {
                        pos = "剧烈运动";
                    }
                    bpBody.setPosition(pos);
                    bpBody.setMethod(method);
                    log.debug("血压数据: " + bpBody.toString());
                    packetType = PacketType.BP_PACKET;
                }
                break;
            case PING_PACKET://心跳包
                packetType = PacketType.PING_PACKET;
                log.debug("收到心跳包");
                break;
            case BP_DAY_TIME://白天测量
                detectTime = ReadUtils.readDetectTime(buf, 2);
                packetType = PacketType.SET_TIME_PACKET;
                log.debug("回复服务器白天测量时间：" + detectTime.toString());
                break;
            case QUERY_DEVINFO:
                break;
            case BP_DAY_DETECT:
                isBegin.setSign(2);
                isBegin.setState(ReadUtils.readData(buf));
                packetType = PacketType.SET_STATE_PACKET;
                log.debug("回复服务器白天测量：：1为开启0为关闭" + isBegin.getState());
                break;
            case BP_NIGHT_DETECT:
                isBegin.setSign(1);
                isBegin.setState(ReadUtils.readData(buf));
                packetType = PacketType.SET_STATE_PACKET;
                log.debug("回复服务器夜间测量：1为开启0为关闭" + isBegin.getState());
                break;
            case BP_NIGHT_TIME://夜间测量
                detectTime = ReadUtils.readDetectTime(buf, 1);
                packetType = PacketType.SET_TIME_PACKET;
                log.debug("回复服务器晚上测量时间间隔：" + detectTime.getIntervalTime());
                break;
            case START_BP_DETECT://开始测量
                byte[] b = new byte[3];
                buf.get(b);
                if ((b[0] & 0x000000ff) == 1) {
                    detectState.setCmd(1);
                    detectState.setStartState(1);
                } else {
                    detectState.setCmd(1);
                    detectState.setStartState(2);
                }
                packetType = PacketType.START_DETECT;
                log.debug("回复服务器开始测量状态：" + detectState.toString());
                break;
            case STOP_BP_DETECT://停止测量
                detectState.setCmd(2);
                detectState.setStartState(1);
                packetType = PacketType.STOP_DETECT;
                log.debug("回复服务器停止测量：" + detectState.toString());
                break;
            case CURRENT_TIME://得到血压计当前时间
                packetType = PacketType.SET_RECTIFY_TIME;
                byte[] bt = new byte[7];
                buf.get(bt);
                int year1 = bt[0] & 0x000000ff;
                int month1 = bt[1] & 0x000000ff;
                int day1 = bt[2] & 0x000000ff;
                int hour1 = bt[3] & 0x000000ff;
                int min1 = bt[4] & 0x000000ff;
                log.debug("回复服务器血压计当前时间：" + year1 +
                        "/" + month1 + "/" + day1 + " " + hour1 + ":" + min1);
                break;
            case DELETE_RECORD://清空记录
                packetType = PacketType.DELETE_RECORD;
                log.debug("回复服务器清空记录：");
                break;
            case ELECTRIC:
                packetType = PacketType.ELECTRIC;
                byte[] bElectric = new byte[3];
                buf.get(bElectric);
                electric = bElectric[0] & 0x000000ff;
                log.info("回复服务器设备电量：" + electric);
                break;
            case GET_BP_RESULT_NUM:
                packetType = PacketType.TOTAL_NUM;
                byte[] bSynData = new byte[3];
                buf.get(bSynData);
                synData = String.valueOf(bSynData[0] & 0x000000ff);
                log.debug("回复服务器总记录数：" + synData);
                break;
            default:
                break;
        }


    }

    @Override
    public byte[] encode() {
        buffer.clear();
        if (synData != null) {
            byte[] synByte = new byte[]{(byte) 0xfa, (byte) 0x0A, (byte) 0x64, (byte) 0x0D,
                    (byte) 0x0B, (byte) 0x14, (byte) 0x0F, (byte) 0x30};
            byte[] bt = DecodeCRC16.Crc16cal1(synByte);
            buffer.put(bt);
            log.info("发出同步数据数据包");
        }
        if (rectify != null) {
            Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH) + 1;
            int date = c.get(Calendar.DATE);
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            int second = c.get(Calendar.SECOND);
            int year1 = Integer.parseInt(String.valueOf(year).substring(2));
            byte[] b = new byte[]{(byte) 0xfa, (byte) 0x0A, (byte) 0x51, (byte) year1,
                    (byte) month, (byte) date, (byte) hour, (byte) minute};
            byte[] bt = DecodeCRC16.Crc16cal1(b);
            buffer.put(bt);
            log.info("发出矫正时间数据包");
        }


        if (deviceId != null) {
            byte[] bs = deviceId.getBytes();
            buffer.put((byte) bs.length);
            buffer.put(bs);
        }
        if (packetType != null) {
            if (packetType == PacketType.PING_PACKET) { //处理心跳包
                byte[] b = {(byte) 0xFA, (byte) 0x05, (byte) 0xA2};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);

            }
        }
        if (detectTime != null) {
            if (detectTime.getSign() == 1) {//设置夜间测量时间
                byte[] b = {(byte) 0xFA, (byte) 0x0B, (byte) 0x56, (byte) detectTime.getStartH(),
                        (byte) detectTime.getStartM(), (byte) detectTime.getEntH(),
                        (byte) detectTime.getEntM(), 0x00, (byte) detectTime.getIntervalTime()};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送夜间测量时间包{}",detectTime.toString());
            }
            if (detectTime.getSign() == 2) {//设置白天测量时间
                byte[] b = {(byte) 0xFA, (byte) 0x0B, (byte) 0x54, (byte) detectTime.getStartH(),
                        (byte) detectTime.getStartM(), (byte) detectTime.getEntH(),
                        (byte) detectTime.getEntM(), 0x00, (byte) detectTime.getIntervalTime()};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送白天测量时间包{}",detectTime.toString());

            }

        }
        if (isBegin != null) {
            if (isBegin.getSign() == 1) {//设置夜间测量状态
                byte[] b = {(byte) 0xFA, (byte) 0x06, (byte) 0x55, (byte) isBegin.getState()};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送夜间测量状态：1为开启0为关闭{}",isBegin.toString());
            }
            if (isBegin.getSign() == 2) {//设置白天测量状态
                byte[] b = {(byte) 0xFA, (byte) 0x06, (byte) 0x53, (byte) isBegin.getState()};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送白天测量状态：1为开启0为关闭{}",isBegin.toString());

            }
        }
        if (detectState != null) {
            if (detectState.getCmd() == 1) {
                byte[] b = {(byte) 0xFA, (byte) 0x05, (byte) 0x70};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送启动测量{}",detectState.toString());
            }
            if (detectState.getCmd() == 2) {
                byte[] b = {(byte) 0xFA, (byte) 0x05, (byte) 0x71};
                byte[] bt = DecodeCRC16.Crc16cal1(b);
                buffer.put(bt);
                log.info("发送停止测量{}",detectState.toString());
            }
        }
        buffer.flip();
        byte[] bs = new byte[buffer.remaining()];
        buffer.get(bs);
        return bs;
    }


}
